<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>bpmn</title>
  <script src="./antvx6.js"></script>
  <script src="./layout.min.js"></script>
</head>

<body>
  <div id="container"></div>
  <script>
    window.onload = function () {
      const Graph = X6.Graph;

      // #region 注册基础图形
      Graph.registerNode(
        'class',
        {
          inherit: 'rect',
          markup: [
            {
              tagName: 'rect',
              selector: 'body',
            },
            {
              tagName: 'rect',
              selector: 'name-rect',
            },
            {
              tagName: 'rect',
              selector: 'attrs-rect',
            },
            {
              tagName: 'rect',
              selector: 'methods-rect',
            },
            {
              tagName: 'text',
              selector: 'name-text',
            },
            {
              tagName: 'text',
              selector: 'attrs-text',
            },
            {
              tagName: 'text',
              selector: 'methods-text',
            },
          ],
          attrs: {
            rect: {
              width: 160,
            },
            body: {
              stroke: '#fff',
            },
            'name-rect': {
              fill: '#5f95ff',
              stroke: '#fff',
              strokeWidth: 0.5,
            },
            'attrs-rect': {
              fill: '#eff4ff',
              stroke: '#fff',
              strokeWidth: 0.5,
            },
            'methods-rect': {
              fill: '#eff4ff',
              stroke: '#fff',
              strokeWidth: 0.5,
            },
            'name-text': {
              ref: 'name-rect',
              refY: 0.5,
              refX: 0.5,
              textAnchor: 'middle',
              fontWeight: 'bold',
              fill: '#fff',
              fontSize: 12,
            },
            'attrs-text': {
              ref: 'attrs-rect',
              refY: 0.5,
              refX: 0.5,
              textAnchor: 'middle',
              fill: 'black',
              fontSize: 10,
            },
            'methods-text': {
              ref: 'methods-rect',
              refY: 0.5,
              refX: 0.5,
              textAnchor: 'middle',
              fill: 'black',
              fontSize: 10,
            },
          },
          propHooks(meta) {
            const { name, budget, number, ...others } = meta
            if (!(name && budget && number)) {
              return meta
            }
            const rects = [
              { type: 'name', text: name },
              { type: 'attrs', text: budget },
              { type: 'methods', text: number },
            ]
            let offsetY = 0
            rects.forEach((rect) => {
              const height = rect.text.length * 12 + 16
              X6.ObjectExt.setByPath(
                others,
                `attrs/${rect.type}-text/text`,
                rect.text.join('\n'),
              )
              X6.ObjectExt.setByPath(others, `attrs/${rect.type}-rect/height`, height)
              X6.ObjectExt.setByPath(
                others,
                `attrs/${rect.type}-rect/transform`,
                'translate(0,' + offsetY + ')',
              )
              offsetY += height
            })
            others.size = { width: 160, height: offsetY }
            return others
          },
        },
        true,
      )
      // 继承
      Graph.registerEdge(
        'extends',
        {
          inherit: 'edge',
          attrs: {
            line: {
              strokeWidth: 1,
              stroke: "#7c68fc", // 指定 path 元素的填充色
            },
          },
        },
        true,
      )
      const graph = new Graph({
        container: document.getElementById('container'),
        width: 800,
        height: 700,
        background: {
          color: '#fff', // 设置画布背景颜色
        },
        grid: {
          size: 10,      // 网格大小 10px
          visible: true, // 渲染网格背景
        },
      })
      const data = [
        {
          "id": "1",
          "shape": "class",
          "name": [
            "工程1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "100亿"
          ],
        },
        {
          "id": "2",
          "shape": "class",
          "name": [
            "子工程1-1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "80亿"
          ],
        },
        {
          "id": "3",
          "shape": "extends",
          "source": "1",
          "target": "2"
        },
        {
          "id": "4",
          "shape": "class",
          "name": [
            "子工程1-2"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "20亿"
          ],
        },
        {
          "id": "5",
          "shape": "extends",
          "source": "1",
          "target": "4"
        },
        {
          "id": "6",
          "shape": "class",
          "name": [
            "子工程1-2-1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "10亿"
          ],
        },
        {
          "id": "7",
          "shape": "extends",
          "source": "4",
          "target": "6"
        },
        {
          "id": "8",
          "shape": "class",
          "name": [
            "子工程1-2-1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "10亿"
          ],
        },
        {
          "id": "9",
          "shape": "extends",
          "source": "1",
          "target": "8"
        },
        {
          "id": "10",
          "shape": "class",
          "name": [
            "子工程1-2-1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "10亿"
          ],
          // "position": {
          //   "x": 400,
          //   "y": 350
          // }
        },
        {
          "id": "11",
          "shape": "extends",
          "source": "8",
          "target": "10"
        },
        {
          "id": "12",
          "shape": "class",
          "name": [
            "子工程1-2-1"
          ],
          "budget": [
            "预算"
          ],
          "number": [
            "10亿"
          ],
          // "position": {
          //   "x": 400,
          //   "y": 350
          // }
        },
        {
          "id": "13",
          "shape": "extends",
          "source": "8",
          "target": "12"
        }
      ]
      let nodes = []
      let edges = []
      let obj = {}
      data.forEach(v => {
        if (v.shape === "class") {
          nodes.push(v)
        }
        if (v.shape === "extends") {
          edges.push(v)
        }
      })
      obj.nodes = nodes
      obj.edges = edges
      const gridLayout = new layout.DagreLayout({
        type: 'dagre',
        rankdir: 'TB',
        align: 'DL',
        ranksep: 50,
        nodesep: 50,
        controlPoints: true,
      })
      const newModel = gridLayout.layout(obj)
      graph.fromJSON(newModel)
    }
  </script>
</body>

</html>